package depta.datarecord;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.htmlparser.Node;
import org.htmlparser.util.NodeList;

import util.nodecloner.ChildFinder;
import util.nodecloner.NodeCloner;

import depta.dataregion.DataRegion;
import depta.dataregion.finder.DataRegionFinder;

public class DataRecordIdentifier {

	private DataRegionFinder drf;

	public DataRecordIdentifier(DataRegionFinder drf){
		
		this.drf = drf;
	
	}
	
	public List<List<DataRegion>> identifyDataRecords(Node node){
		
		DataRegionFinder finder = new DataRegionFinder(drf.getMdr(), drf.getK(), drf.getThreshold());
		
		List<DataRegion> list = drf.getDataRegion(node);
		
		List<List<DataRegion>> finalDataRecords = new ArrayList<List<DataRegion>>(list.size());
		
		for (DataRegion dataRegion : list) {
			
			List<Node> generalizedNodes = dataRegion.getGeneralizedNodes();			
			
			Node tree = NodeCloner.clone(node, false, false);
			
			for (Node tbchild : generalizedNodes) {
			
				ChildFinder.getChildren(tree).add(tbchild);
			
			}
			
			List<DataRegion> dataRecords = finder.findDRs(tree);
			
			boolean valid = true;
			
			if (coverAllDataItems(generalizedNodes,dataRecords)){
				
				for (DataRegion dataRecord : dataRecords) {
					
					if (isTooSmall(dataRecord)){
						valid = false;
						break;
					}
					
				}
				
			}else{
				valid = false;
			}
			
			if (valid){
				
				finalDataRecords.add(dataRecords);
				
			}else{

				List<DataRegion> dr = new ArrayList<DataRegion>();
				dr.add(dataRegion);
				finalDataRecords.add(dr);
				
			}
			
		}
		
		return finalDataRecords;

	}

	private boolean isTooSmall(DataRegion dataRecord) {
	
		// TODO Auto-generated method stub
		return false;
	
	}

	private boolean coverAllDataItems(List<Node> generalizedNodes,
			List<DataRegion> dataRecords) {
		
		Set<Node> gN = new HashSet<Node>();
		
		for (Node node : generalizedNodes) {
		
			gN.addAll(getDataItems(node));
		
		}
		
		Set<Node> dR = new HashSet<Node>();
		
		for (DataRegion dataRecord : dataRecords) {
			
			List<Node> gn = dataRecord.getGeneralizedNodes();
			
			for (Node node : gn) {
				
				dR.addAll(getDataItems(node));
				
			}
			
		}
		
		if (dR.containsAll(gN))
			return true;
		
		return false;
		
	}

	private Set<Node> getDataItems(Node node) {
		
		if (ChildFinder.hasChildren(node)){
			
			Set<Node> ret = new HashSet<Node>();
			
			NodeList children = ChildFinder.getChildren(node);
			
			for (int i = 0; i < children.size(); i++) {
				ret.addAll(getDataItems(children.elementAt(i)));
			}
			
			return ret;
			
		}else{
			
			Set<Node> ret = new HashSet<Node>();
			
			ret.add(node);
			return ret;
		}
		
	}
	
}
